<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>jstests thesis</title>
    </head>
    <body id="body">
		<div id="container">
			<p onclick="alert(this.id);" id="tag1">value1</p>
			<p id="tag2">value2</p>
		</div>
		<div id="content" class="lol">
			<p>content example</p>
		</div>
		<div class="lol">
			<ul id="successlist" style="color:#1D1;">
			</ul>
		</div>
	
		<a href="#" id="linkedit">linktest</a>
		<input id="narcUid383" value="test" onclick="testOnclick();return false;" type="button">
		<input id="narcUid384" value="test2" onclick="alert(getText(document.getElementById('successlist').childNodes));return false;" type="button">
		
			<script type="text/javascript">function AssertError(message) {
    this.name = "AssertError";
    this.message = message || "Assertion failed";
}
AssertError.prototype = new Error();
AssertError.prototype.constructor = AssertError;

/*
 * assertEq(actual, expected [, message])
 *   Throw if the two arguments are not the same.  The sameness of two values
 *   is determined as follows.  If both values are zero, they are the same iff
 *   their signs are the same.  Otherwise, if both values are NaN, they are the
 *   same.  Otherwise, they are the same if they compare equal using ===.
 * see https://bugzilla.mozilla.org/show_bug.cgi?id=480199 and
 *     https://bugzilla.mozilla.org/show_bug.cgi?id=515285
 */
var assertEquals =
    function (actual, expected, message)
    {
      function SameValue(v1, v2)
      {
        if (v1 === 0 && v2 === 0)
          return 1 / v1 === 1 / v2;
        if (v1 !== v1 && v2 !== v2)
          return true;
        return v1 === v2;
      }
      if (!SameValue(actual, expected))
      {
        throw new AssertError('Assertion failed: got "' + actual + '", expected "' + expected + '"' +
                            (message ? ": " + message : ""));
      }
    };

function assertTrue(actual) {
    assertEquals(actual, true);
}

function assertFalse(actual) {
    assertEquals(actual, false);
}
function mainchapter(message)
{
	var newli = document.createElement("li"),newli2 = document.createElement("li");
	newli.appendChild(document.createTextNode("--------------------------------------------------------------------"));
	newli.style.color = "#333";
	newli2.appendChild(document.createTextNode(message));
	newli2.style.color = "#666";
	newli2.style.fontWeight = "bold";
	document.getElementById("successlist").appendChild(newli);
	document.getElementById("successlist").appendChild(newli2);
}
function chapter(message)
{
	var newli = document.createElement("li");
	newli.appendChild(document.createTextNode(message));
	newli.style.color = "#33A";
	document.getElementById("successlist").appendChild(newli);
}
function success(message)
{
	var newli = document.createElement("li");
	newli.appendChild(document.createTextNode(message));
	newli.style.color = "#4A3";
	document.getElementById("successlist").appendChild(newli);
}
function $ERROR(message){
	var newli = document.createElement("li");
	newli.appendChild(document.createTextNode(message));
	newli.style.color = "#A33";
	document.getElementById("successlist").appendChild(newli);
}</script><script type="text/javascript"><br />
<b>Warning</b>:  file_get_contents() [<a href='function.file-get-contents'>function.file-get-contents</a>]: Unable to access oojtests/chapter1.js in <b>/home/biking/domains/bikingladies.be/public_html/kul/jstest/index.php</b> on line <b>34</b><br />
<br />
<b>Warning</b>:  file_get_contents(oojtests/chapter1.js) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: No such file or directory in <b>/home/biking/domains/bikingladies.be/public_html/kul/jstest/index.php</b> on line <b>34</b><br />
</script><script type="text/javascript">// CHAPTER 2 OF OBJECT ORIENTED JAVASCRIPT
// PRIMITIVE DATA TYPES, Arrays, Loops, and conditions
mainchapter("2 PRIMITIVE DATA TYPES, Arrays, Loops, and conditions");

(function(){
	try{
		// 2.1 VARIABLES
		chapter("2.1 VARIABLES");
		var a;
		var thisIsAVariable;
		var _and_this_too;
		var mix12three;
		assertEquals(a,undefined); // scope issue..
		success("2.1.1a DECLARE VALID VARIABLES");
	}catch(e){
		$ERROR("2.1.1a DECLARE VARIABLE FAILED: "+e.message);
	}
	try{
		eval("var 2trhee4five"); // var can't start with a number
		$ERROR("2.1.1b variable name can't start with a number");
	}catch(e){
		success("2.1.1b DENY DECLARE INVALID VARIABLES: "+e.message);
	}
	try{
		// simple assigns
		var a = 1;
		var v1,v2,v3= 'hello', v4 = 4, v5;
		assertEquals(a,1);
		assertEquals(v1,undefined);
		assertEquals(v3,'hello');
		assertEquals(v4,4);
		// case sensitive
		var case_matters = 'lower';
		var CASE_MATTERS = 'upper';
		assertEquals(case_matters,'lower');
		assertEquals(CASE_MATTERS,'upper');
		success("2.1.2 ASSIGN VARIABLES");
	}catch(e){
		$ERROR("2.1.2 ASSIGN VARIABLES: "+e.message);
	}
	try{
		eval("onbekende_var;");
		$ERROR("2.1.3 ACCESS UNDEFINED VARIABLES > ERROR EXPECTED");
	}catch(e){
		success("2.1.3 ACCESS UNDEFINED VARIABLES / ERROR EXCPETED: "+e.message);
	}
})();

// execute thisone in the global scope, refreshing causes narcissus to cache this
try{
	var unique_var_name;
	assertEquals(unique_var_name,undefined); // scope issue..
	unique_var_name = 2;
	success("2.1.4 GLOBAL VARIABLES ARE NOT CACHED");
}catch(e){
	$ERROR("2.1.4 GLOBAL VARIABLE WAS CACHED : "+e.message);
}

(function(){
	// 2.2 OPERATORS
	chapter("2.2 OPERATORS");
	try{
		assertEquals(1+2,3);
		var a = 1;
		var b = 2;
		assertEquals(a+1,2);
		assertEquals(b+2,4);
		assertEquals(a+b,3);
		var c = a+b;
		assertEquals(c,3);
		success("2.2.1a OPERATORS +");
	}catch(e){
		$ERROR("2.2.1a OPERATORS +: "+e.message);
	}
	try{
		assertEquals(6%3,0);
		assertEquals(5%3,2);
		success("2.2.1b OPERATORS %");
	}catch(e){
		$ERROR("2.2.1b OPERATORS %: "+e.message);
	}
	try{
		var a = 123; var b= a++;
		assertEquals(b,123);
		assertEquals(a,124);
		var c = 123; var d= ++c;
		assertEquals(d,124);
		assertEquals(c,124);
		success("2.2.1c OPERATORS ++ prefix/suffix");
	}catch(e){
		$ERROR("2.2.1c OPERATORS ++: "+e.message);
	}
	try{
		var a = 123; var b= a--;
		assertEquals(b,123);
		assertEquals(a,122);
		var c = 123; var d= --c;
		assertEquals(d,122);
		assertEquals(c,122);
		success("2.2.1d OPERATORS -- prefix/suffix");
	}catch(e){
		$ERROR("2.2.1d OPERATORS -- : "+e.message);
	}
	try{
		var a=5;
		a += 3;
		assertEquals(a,8);
		a -= 3;
		assertEquals(a,5);
		a*=2;
		assertEquals(a,10);
		a /= 5;
		assertEquals(a,2);
		a %= 2;
		assertEquals(a,0);
		success("2.2.1e OPERATORS +=, -=, *=, /=, %=");
	}catch(e){
		$ERROR("2.2.1e OPERATORS +=, -=, *=, /=, %=: "+e.message);
	}
	try{
		assertEquals(1 + 2 * 3 , 7);
		assertEquals(1 + (2 * 3) , 7);
		assertEquals((1 + 2) * 3 , 9);
		success("2.2.2 OPERATOR PRECEDENCE");
	}catch(e){
		$ERROR("2.2.2 OPERATOR PRECEDENCE: "+e.message);
	}
	try{
		var b = 5;
		assertEquals(true || (b=6),true);
		assertEquals(b,5);
		assertEquals(true && (b=6),6);
		assertEquals(b,6);
		assertEquals(true || "something",true);
		assertEquals(true && "something","something");
		success("2.2.3 LAZY EVALUATION");
	}catch(e){
		$ERROR("2.2.3 LAZY EVALUATION: "+e.message);
	}
	
})();

(function(){
	// 2.3 NUMBERS
	chapter("2.3 STRINGS");
	try{
		var n = 1;
		assertEquals(typeof n,"number");
		n = 1234;
		assertEquals(typeof n,"number");
		var n2 = 1.23;
		assertEquals(typeof n2,"number");
		assertEquals(typeof 123,"number");
		success("2.3.1 typeof, number (ints and floats)");
	}catch(e){
		$ERROR("2.3.1 typeof, number (ints and floats): "+e.message);
	}
	try{
		var n3 = 0377;
		assertEquals(typeof n3,"number");
		assertEquals(n3,255);
		success("2.3.2 octal numbers");
	}catch(e){
		$ERROR("2.3.2 octal numbers: "+e.message);
	}
	try{
		var n4 = 0x00;
		assertEquals(typeof n4,"number");
		assertEquals(n4,0);
		var n5 = 0xff;
		assertEquals(typeof n5,"number");
		assertEquals(n5,255);
		success("2.3.3 hexadecimal numbers");
	}catch(e){
		$ERROR("2.3.3 hexadecimal numbers: "+e.message);
	}
	try{
		assertEquals(1e1,10);
		assertEquals(1e+1,10);
		assertEquals(2e+3,2000);
		assertEquals(typeof 2e+3,"number");	
		success("2.3.4a exponent literals positive (e.g. 2e+3)");
		assertEquals(typeof 2e-3,"number");	
		assertEquals(2e-3,(0.002));
		assertEquals(123.456E-3,0.123456);
		success("2.3.4b exponent literals negative (e.g. 2e-3)");
	}catch(e){
		$ERROR("2.3.4 exponent literals: "+e.message);
	}
	try{
		assertEquals(1e309,Infinity);
		assertEquals(1e308,1e+308);
		var a = 6/0;
		assertEquals(a,Infinity);
		var i = -Infinity;
		assertEquals(i,-Infinity);
		assertEquals(typeof i,"number");
		assertEquals(Infinity-Infinity,NaN);
		assertEquals(Infinity-20,Infinity);
		assertEquals(Infinity*3,Infinity);
		assertEquals(Infinity/2,Infinity);
		success("2.3.5 Infinity");
	}catch(e){
		$ERROR("2.3.5 Infinity: "+e.message);
	}
	try{
		assertEquals(typeof NaN,"number");
		var a = NaN;
		assertEquals(a,NaN);
		var b = 10 * "f";
		assertEquals(b,NaN);
		assertEquals(1+2+NaN,NaN);
		var i = 1 + undefined;
		assertEquals(i,NaN);
		assertEquals(1*undefined,NaN);
		success("2.3.6 NaN");
	}catch(e){
		$ERROR("2.3.6 NaN: "+e.message);
	}
})();

(function(){
	// 2.4 Strings
	chapter("2.4 STRINGS");
	try{
		var s = "some characters";
		assertEquals(typeof s,"string");
		var s = 'some characters and numbers 123 5.87';
		assertEquals(typeof s,"string");
		var s = '1';
		assertEquals(typeof s,"string");
		var s = "";
		assertEquals(typeof s,"string");
		success("2.4.1 typeof string");
	}catch(e){
		$ERROR("2.4.1 typeof string : "+e.message);
	}
	try{
		var s1 = "one"; var s2 = "two"; var s = s1+s2;
		assertEquals(typeof s,"string");
		assertEquals(s,"onetwo");
		success("2.4.2 concat string");
	}catch(e){
		$ERROR("2.4.2 concat string : "+e.message);
	}
	try{
		var s = '1'; s = 3*s;
		assertEquals(typeof s,"number");
		assertEquals(s,3);
		var s = "100";
		assertEquals(typeof s,"string");
		s = s*1;
		assertEquals(typeof s,"number");
		var d = '101 dalmatians';
		assertEquals(d*1,NaN);
		var n = 1;
		assertEquals(typeof n,"number");
		n = "" + n;
		assertEquals(typeof n,"string");
		assertEquals(n,"1");
		success("2.4.3 string conversions");
	}catch(e){
		$ERROR("2.4.3 string conversions: "+e.message);
	}
})();

(function(){
	// 2.5 Booleans
	chapter("2.5 BOOLEANS AND LOGICAL OPERATORS");
	try{
		var b = true;
		assertEquals(typeof b,"boolean");
		var b = false;
		assertEquals(typeof b,"boolean");
		var b = "true";
		assertEquals(typeof b,"string");
		success("2.5.1 typeof boolean");
	}catch(e){
		$ERROR("2.5.1 typeof boolean : "+e.message);
	}
	try{
		var b = !true;
		assertEquals(b,false);
		var b = !!true;
		assertEquals(b,true);
		success("2.5.2a LOGICAL OPERATORS: !not");
	}catch(e){
		$ERROR("2.5.2 LOGICAL OPERATORS : "+e.message);
	}
	try{
		assertEquals(true && true,true);
		assertEquals(true && false,false);
		assertEquals(false && true,false);
		assertEquals(false && false,false);
		assertEquals(true || true,true);
		assertEquals(true || false,true);
		assertEquals(false || true,true);
		assertEquals(false || false,false);
		success("2.5.2b LOGICAL OPERATORS: && ||");
	}catch(e){
		$ERROR("2.5.2 LOGICAL OPERATORS : "+e.message);
	}
	try{
		assertEquals(!!undefined,false);
		assertEquals(!!null,false);
		success("2.5.3 BOOLEAN CONVERSION");
	}catch(e){
		$ERROR("2.5.3 BOOLEAN CONVERSION : "+e.message);
	}
})();

(function(){
	// 2.6 COMPARISON
	chapter("2.6 COMPARISON");
	try{
		assertEquals(1 == 1,true);
		assertEquals(1 == 2,false);
		assertEquals(1 == '1',true);
		assertEquals(1 === '1',false);
		assertEquals(1 === 1,true);
		success("2.6a COMPARISON OPERATORS ==");
	}catch(e){
		$ERROR("2.6a COMPARISON OPERATORS == : "+e.message);
	}
	try{
		assertEquals(1 != 1,false);
		assertEquals(1 != '1',false);
		assertEquals(1 != 2,true);
		assertEquals(1 !== 1,false);
		assertEquals(1 !== '1',true);
		success("2.6b COMPARISON OPERATORS !=");
	}catch(e){
		$ERROR("2.6b COMPARISON OPERATORS != : "+e.message);
	}
	try{
		assertEquals(1 > 1,false);
		assertEquals(33 > 22,true);
		assertEquals(1 >= 1,true);
		assertEquals(1 < 1,false);
		assertEquals(1 < 2,true);
		assertEquals(1 <= 1,true);
		assertEquals(1 <= 2,true);
		success("2.6c COMPARISON OPERATORS > <");
	}catch(e){
		$ERROR("2.6c COMPARISON OPERATORS > < : "+e.message);
	}
})();

(function(){
	// 2.7 ARRAYS
	chapter("2.7 ARRAYS");
	try{
		var a = [];
		assertEquals(typeof a, "object");
		var a = [1,2,3];
		assertEquals(a[0],1);
		assertEquals(a[1],2);
		success("2.7.1 Init Arrays ");
	}catch(e){
		$ERROR("2.7.1 Init Arrays : "+e.message);
	}
	try{
		var a = [1,2,3];
		a[2] = "three";
		assertEquals(a[0],1);
		assertEquals(a[2],"three");
		a[3] = "four";
		assertEquals(a[1],2);
		assertEquals(a[3],"four");
		var a = [1,2,3];
		a[6] = 'new';
		assertEquals(a[1],2);
		assertEquals(a[4],undefined);
		assertEquals(a[5],undefined);
		assertEquals(a[6],'new');
		success("2.7.2 Adding/Updating Arrays ");
	}catch(e){
		$ERROR("2.7.2  Adding/Updating Arrays : "+e.message);
	}
	try{
		var a = [1,2,3];
		assertEquals(delete a[1],true);
		assertEquals(a[1],undefined);
		assertEquals(a[2],3);
		success("2.7.3 Deleting elements from Arrays ");
	}catch(e){
		$ERROR("2.7.3 Deleting elements from Arrays : "+e.message);
	}	
	try{
		var a = [1,"two",false,null,undefined];
		assertEquals(a[0],1);
		assertEquals(a[1],"two");
		assertEquals(a[2],false);
		assertEquals(a[3],null);
		assertEquals(a[4],undefined);
		a[5] = [1,2,3];
		assertEquals(a[5][0],1);
		assertEquals(a[5][2],3);
		var a = [[1,2,3],[4,5,6]];
		assertEquals(a[0][1],2);
		assertEquals(a[1][1],5);
		success("2.7.4 Arrays of Arrays ");
	}catch(e){
		$ERROR("2.7.4 Arrays of Arrays : "+e.message);
	}
	try{
		var s = 'one';
		assertEquals(s[0],'o');
		assertEquals(s[1],'n');
		success("2.7.5 String Arrays ");
	}catch(e){
		$ERROR("2.7.5 String Arrays : "+e.message);
	}
})();

(function(){
	// 2.8 CONDITIONS AND LOOPS
	chapter("2.8 CONDITIONS AND LOOPS");
	try{
		if(false)
		{
			$ERROR("2.8.1 IF-STATEMENT");
		}
		var result="", somevar = undefined;
		if(typeof somevar !== "undefined"){result = "yes";}
		assertEquals(result,"");
		somevar = 123;
		if(typeof somevar !== "undefined"){result = "yes";}
		assertEquals(result,"yes");
		result = (somevar === 123 ? "equal" : "notequal");
		assertEquals(result,"equal");
		result = (somevar === 122 ? "equal" : "notequal");
		assertEquals(result,"notequal");
		success("2.8.1 IF-STATEMENT");
	}catch(e){
		$ERROR("2.8.1 IF-STATEMENT : "+e.message);
	}
	try{
		var a = '1';result = "";
		switch(a)
		{
			case 1:
				$ERROR("2.8.2 SWITCH ('1' === 1) ");break;
			case '1':
				result = "ok";
				break;
			default:
				$ERROR("2.8.2 SWITCH default ");break;
		}
		switch(a)
		{
			case 2:
				$ERROR("2.8.2 SWITCH ('1' === 2) ");break;
			case '2':
				$ERROR("2.8.2 SWITCH ('1' === '2' ");break;
			default:
				result = "ok2";
				break;
		}
		assertEquals(result,"ok2");
		success("2.8.2 SWITCH");
	}catch(e){
		$ERROR("2.8.2 SWITCH : "+e.message);
	}
	try{
		var i = 0;
		while(i < 10)
		{
			i++;
		}
		assertEquals(i,10);
		var i = 0;
		do
		{
			i++;
		}while(i < 5)
		assertEquals(i,5);
		success("2.8.3 WHILE / DO WHILE");
	}catch(e){
		$ERROR("2.8.3 WHILE / DO WHILE : "+e.message);
	}
	try{
		var result = 0;
		for(var i = 0; i<10;i++){
			result += 10;
		}
		assertEquals(result,100);
		for(var i = 0,result=0;i<10;i++,result+=5){
			// nothing here
		}
		assertEquals(result,50);
		var i = 0,result = 1000;
		for(;;){
			result+=10;
			if(++i == 5){
				break;
			}
		}
		assertEquals(result,1050);
		success("2.8.4a FOR-LOOP");
		var a = ["a","b","c","d","e"],result = "";
		for(var i in a)
		{
			result +=a [i];
		}
		assertEquals(result,"abcde");
		success("2.8.4b FOR IN LOOP");
	}catch(e){
		$ERROR("2.8.4 FOR-LOOP : "+e.message);
	}
})();



</script><script type="text/javascript">// CHAPTER 3 OF OBJECT ORIENTED JAVASCRIPT
// FUNCTIONS
mainchapter("3 FUNCTIONS");

(function(){
	// 3.1 Calling a function
	chapter("3.1 Define / Call a function");
	try{
		function sum(a,b){
			var c = a + b;
			return c;
		}
		success("3.1a Define a function");
		assertEquals(3,sum(1,2));
		assertEquals(NaN,sum(1));
		assertEquals(NaN,sum(1));
		assertEquals(3,sum(1,2,3,4,5));
		success("3.1b Call a function");
		function args(){ return arguments;} // possible thanks to the arguments array that is created inside each function
		var myArgs = args("test");
		assertEquals(myArgs[0],"test");
		function sumOnSteroids(){
			var i, res = 0;
			var number_of_params = arguments.length;
			for(i=0;i<number_of_params;i++){
				res+=arguments[i];
			}
			return res;
		}
		assertEquals(sumOnSteroids(1,2,3,4,5),15);
		success("3.1c Array of arguments available in function");
		try{
			// eval("this_is_not_a_function();"); // narcissus stops executing after this line
			// $ERROR("Calling an undefined function throws no error");
			$ERROR("Narcissus crashes with undefined_function_call(); (also when surrounded with try/catch)");
			$ERROR("Narcissus crashes with eval('undefined_function_call();');");
		}
		catch(e){
			success("3.1e Can not call an undefined function");
		}
	}catch(e){
		$ERROR("3.1 Define / Call a function : "+e.message);
	}
})();

(function(){
	chapter("3.2 BUILTIN FUNCTIONS (DONE)");
})();

(function(){
	// 3.3 SCOPE OF VARIABLES
	chapter("3.3 SCOPE OF VARIABLES");
	try{
		var global_var = 1;
		var f = function() {
			var local = 2;
			global_var++;
			return global_var;
		}
		assertEquals(f(),2);
		assertEquals(f(),3);
		success("3.3.1a Access to global property (literal notation)");
		try{
			eval("local;");
			eval("if(local === undefined) throw new AssertError('NOTE: local undefined OK // ERROR THROWN NOK !! @SEE 2.1.3');");
			$ERROR("3.3.1b ACCESSED LOCAL PROPERTY, ERROR EXCPECTED (literal notation)");
		}catch(e){
			success("3.3.1b No access to local property (literal notation): "+e.message);
		}
		var global_var2 = 1;
		function f2() {
			var local2 = 2;
			global_var2++;
			return global_var2;
		}
		assertEquals(f2(),2);
		assertEquals(f2(),3);
		success("3.3.1c Access to global property (normal notation)");
		assertEquals(typeof local2,"undefined");
		success("3.3.1d No access to local property (normal notation)");
	}catch(e){
		$ERROR("3.3.1 SCOPE PROBLEM : "+e.message);
	}
	try{
		var a = 123;
		function f(){
			assertEquals(a,undefined);
			var a = 1;
			assertEquals(a,1);
		}
		f();
		assertEquals(a,123);
		success("3.3.2 Variable name reused");
	}catch(e){
		$ERROR("3.3.2 Variable name reused : "+e.message);
	}
})();

(function(){
	// 3.4 FUNCTIONS AS DATA
	chapter("3.4 FUNCTIONS AS DATA");
	try{
		function f(){return 1;}
		assertEquals(typeof f,"function");
		success("3.4a normal function notation");
		var f2 = function(){return 1;}
		assertEquals(typeof f2,"function");
		success("3.4b function literal notation");
		// You can use the delete operator to delete variables declared implicitly but not those declared with the var statement.
		sum = function(a,b){return a+b;}
		add = sum;
		delete sum;
		assertEquals(typeof sum,"undefined","sum must be undefined");
		assertEquals(typeof add,"function","add is not a function");
		assertEquals(add(1,2),3,"add is not working properly");
	}catch(e){
		$ERROR("3.4 FUNCTION AS DATA : "+e.message);
	}
})();

(function(){
	// 3.5 CALLBACK FUNCTIONS
	chapter("3.5 CALLBACK FUNCTIONS");
	try{
		function invoke_and_add(a, b){
			return a() + b();
		}
		function one(){
			return 1;
		}
		function two(){
			return 2;
		}
		assertEquals(invoke_and_add(one,two),3);
		success("3.5a functions as paramaters");
		function addOne(a){return a+1;}
		function multiplyByTwo(a, b, c, callback)
		{
			var i, ar = [];
			for(i = 0; i < 3; i++)
			{
				ar[i] = callback(arguments[i]*2);
			}
			return ar;
		}
		var nr_list = multiplyByTwo(1,2,3,addOne);
		assertEquals(nr_list[0],3);
		assertEquals(nr_list[2],7);
		success("3.5b callback function with paramaters");
	}catch(e){
		$ERROR("3.5 CALLBACK FUNCTIONS : "+e.message);
	}
})();

(function(){
	// 3.6 SELF INVOKING FUNCTIONS
	chapter("3.6 SELF INVOKING FUNCTIONS");
	try{
		var a = (function(){
			return 1;
		})();
		assertEquals(a,1);
		success("3.6 function called automatically");
	}catch(e){
		$ERROR("3.6 Function not called : "+e.message);
	}
})();

(function(){
	// 3.7 inner (Private) Functions
	chapter("3.7 inner (Private) Functions");
	try{
		var a = function(param){
			var localf = function(theinput){
				return theinput * 2;
			};
			return localf(param);
		};
		assertEquals(a(2),4);
		success("3.7a inner function executed in scope");
		assertEquals(typeof localf,"undefined");
		success("3.7b inner function unaccessible out of scope");
	}catch(e){
		$ERROR("3.7 inner (Private) Functions : "+e.message);
	}
})();

(function(){
	// 3.8 FUNCTIONS RETURN FUNCTIONS
	chapter("3.8 FUNCTIONS RETURN FUNCTIONS");
	try{
		var result = 1;
		var literal_a = function(){
			result = 10;
			return function(){
				result = 20;
			}
		}
		var fn_a = literal_a();
		assertEquals(result,10);
		fn_a();
		assertEquals(result,20);
		success("3.8a functions returned correct (literal notation)");
		literal_a = literal_a();
		assertEquals(result,10);
		literal_a();
		assertEquals(result,20);
		success("3.8b function rewrites thyself");
		var result2 = 1;
		function normal_a(){
			result2 = 10;
			return function(){
				result2 = 20;
			}
		}
		var fn_a = normal_a();
		assertEquals(result2,10);
		fn_a();
		assertEquals(result2,20);
		success("3.8c functions returned correct (normal notation)");
	}catch(e){
		$ERROR("3.8 function returns function : "+e.message);
	}
})();

(function(){
	// 3.9 CLOSURES IN FUNCTIONS
	chapter("3.9 SCOPE / CLOSURES IN FUNCTIONS");
	try{
		var a = 1; 
		var f = function(){var local = 1;return a;}
		assertEquals(f(),1);
		success("3.9.1a global variable updated");
		assertEquals(typeof local,"undefined");
		success("3.9.1b local variable unaccessible");
		var f1 = function(){var local_a = 1; return f2();}
		var f2 = function(){return local_a;}
		try{
			var result = f1();
			try{
				assertEquals(typeof result,"undefined");
				success("3.9.1c local variable is undefined // NOTE: NO ERROR WAS THROWN WHILE EXECUTED");
			}catch(e){
				$ERROR("3.9.1c FUNCTION EXECUTED WITH undefined Variable");				
			}
		}catch(e){
			success("3.9.1c Function with unknown var > ERROR : "+e.message);
		}
		// You can use the delete operator to delete variables declared implicitly but not those declared with the var statement.
		local_a = 5; 
		assertEquals(f1(),5);
		local_a = 55;
		assertEquals(f1(),55);
		success("3.9.1d var introduced after function");
		delete local_a;
		try{
			var result = f1();
			try{
				assertEquals(typeof result,"undefined");
				success("3.9.1e DELETED variable is undefined // NOTE: NO ERROR WAS THROWN WHILE EXECUTED");
			}catch(e){
				$ERROR("3.9.1e FUNCTION EXECUTED WITH DELETED Variable");				
			}
		}catch(e){
			success("3.9.1e Function with deleted var > ERROR : "+e.message);
		}
	}catch(e){
		$ERROR("3.9.1 SCOPE IN FUNCTIONS : "+e.message);
	}	
	try{
		var f = function(){
			var b = "b";
			return function(){
				return b;
			}
		}
		assertEquals(typeof b, "undefined");
		var n = f();
		assertEquals(n(),"b");
		success("3.9.2a CLOSURE example 1")
		var n;
		var f2 = function(){
			var b = "b";
			n = function(){
				return b;
			}
		}
		assertEquals(n(),"b");
		success("3.9.2b CLOSURE example 2");
		var f3 = function(arg){
			var n = function(){
				return arg;
			};
			arg++;
			return n;
		}
		var m = f3(123);
		assertEquals(m(),124);
		assertEquals(m(),124);
		success("3.9.2c CLOSURE example 3");
	}catch(e){
		$ERROR("3.9.2 CLOSURES IN FUNCTIONS : "+e.message);
	}
	try{
		var f = function(){
			var a = [];
			var i;
			for(i = 0; i < 3; i++)
			{
				a[i] = function(){
					return i;
				}
			}
			return a;
		}
		var a = f();
		assertEquals(a[0](),3);
		assertEquals(a[1](),3);
		assertEquals(a[2](),3);
		success("3.9.3a CLOSURE IN A LOOP example 1");
		var f = function(){
			var a = [];
			var i;
			for(i = 0; i < 3; i++)
			{
				a[i] = (function(x){
							return function(){
								return x;
							}
				})(i);
			}
			return a;
		}
		var a = f();
		assertEquals(a[0](),0);
		assertEquals(a[1](),1);
		assertEquals(a[2](),2);
		success("3.9.3b CLOSURE IN A LOOP example 2");
	}catch(e){
		$ERROR("3.9.3 CLOSURES IN A LOOP : "+e.message);
	}
})();


(function(){
	// 3.10 FUNCTION EXAMPLES
	chapter("3.10 FUNCTION EXAMPLES");
	try{
		var getValue,setValue;
		(function(){
			var secret = 0;
			getValue = function(){
				return secret;
			};
			setValue = function(v){
				secret = v;
			};
		})();
		assertEquals(getValue(),0);
		setValue(123);
		assertEquals(getValue(),123);
		success("3.10a GETTER/SETTER");
		var setup = function(x){
			var i = 0;
			return function(){
				return x[i++];
			};
		}
		var next = setup(['a','b','c']);
		assertEquals(next(),'a');
		assertEquals(next(),'b');
		assertEquals(next(),'c');
		success("3.10b Iterator");
	}catch(e){
		$ERROR("3.10 FUNCTION EXAMPLES : "+e.message);
	}
})();




</script><script type="text/javascript">// CHAPTER 4 OF OBJECT ORIENTED JAVASCRIPT
// OBJECTS
mainchapter("4 OBJECTS");

(function(){
	// 4.1 Elements Properties Methods
	chapter("4.1 Elements, Properties, Methods");
	try{
		var hero = {
			breed: 'Turtle',
			occupation: 'Ninja'
		};
		assertEquals(hero.breed,'Turtle');
		success("4.1.1a Simple access properties (object.prop notation)");
		assertEquals(hero["occupation"],'Ninja');
		success("4.1.1b Simple access properties (object['prop'] notation)");
		var testprop = {
			normal : "normal",
			'squoted' : "squoted",
			"dquoted" : "dquoted"
		}
		assertEquals(testprop.normal,"normal");
		assertEquals(testprop.squoted,"squoted");
		assertEquals(testprop.dquoted,"dquoted");
		success("4.1.1c Single/double quoted properties");
		var dog = {
			name : 'Benji',
			talk : function() {
				return "woof";
			}
		};
		assertEquals(dog.talk(),"woof");
		assertEquals(dog["talk"](),"woof");
		success("4.1.1d Function as an object property");
		var book = {
			name: 'Catch-22',
			published: 1961,
			author: {
				firstname: 'Joseph',
				lastname: 'Heller'
			}
		}
		assertEquals(book.author.lastname,"Heller");
		assertEquals(book["author"]["lastname"],"Heller");
		assertEquals(book["author"].lastname,"Heller");
		success("4.1.1e Object as Property of an Object");
	}catch(e){
		$ERROR("4.1.1 Accessing Elements, Properties, Methods : "+e.message);
	}
	try{
		var hero = {};
		assertEquals(typeof hero.breed,"undefined");
		hero.breed = 'turtle';
		hero.name = 'Leonardo';
		hero.sayName = function(){return hero.name;};
		assertEquals(hero.sayName(),"Leonardo");
		assertEquals(delete hero.name,true);
		success("4.1.2a Deleted a property");
		assertEquals(hero.sayName(),undefined);
		success("4.1.2b Function that returned a deleted property gives undefined");
	}catch(e){
		$ERROR("4.1.2 Altering Elements, Properties, Methods : "+e.message);
	}
})();

(function(){
	// 4.2 CONSTRUCTOR FUNCTIONS
	chapter("4.2 CONSTRUCTOR FUNCTIONS");
	try{
		function Hero(name){
			this.occupation = 'Ninja';
			this.name = name;
			this.whoareyou = function(){
				return this.name;
			}
		}
		var hero = new Hero("Sam");
		assertEquals(hero.occupation,'Ninja');
		success("4.2a can construct an object and access property");
		assertEquals(hero.name,'Sam');
		assertEquals(hero.whoareyou(),'Sam');
		success("4.2b can construct object with param and access it");
		assertEquals(typeof hero,"object");
		success("4.2c The constructed object is typeof object");
		//var h = Hero("Andy");
		//assertEquals(this.name,"Andy");
		$ERROR("NARCISSUS crashes when calling constructor without new keyword (when using this.property and accessing the global scope)");
	}catch(e){
		$ERROR("4.2 Error with constructor : "+e.message);
	}
})();

(function(){
	// 4.3 INSTANCEOF OPERATOR
	chapter("4.3 INSTANCEOF OPERATOR");
	try{
		function Hero(){}
		var inst_hero = new Hero();
		var inst_o = {};
		assertEquals(inst_hero instanceof Hero,true,"hero must be an instance of a Hero");
		success("4.3a The var hero is a Hero");
		assertEquals(inst_o instanceof Object,true,"{} is an Object");
		success("4.3b {} is an Object");
		// FAILS IN IE,FF(spidermonkey) TOO
		assertEquals(inst_hero instanceof Object,false,"The var hero must not be an Object");
		success("4.3c The var hero is not an Object");
	}catch(e){
		$ERROR("4.3 INSTANCEOF OPERATOR : "+e.message);
	}
})();

(function(){
	// 4.4 FUNCTIONS THAT RETURN OBJECTS
	chapter("4.4 FUNCTIONS THAT RETURN OBJECTS");
	try{
		function factory(name){
			return {
				name: name
			};
		}
		var o = factory('one');
		assertEquals(o.name,'one');
		success("4.4a Object factory");
		function C(){this.a = 1; return {b: 2};}
		var c = new C();
		assertEquals(typeof c.a, "undefined");
		assertEquals(c.b, 2);
		success("4.4b Constructor returns object");
	}catch(e){
		$ERROR("4.4 FUNCTIONS THAT RETURN OBJECTS : "+e.message);
	}
})();

(function(){
	// 4.5 PASSING OBJECTS
	chapter("4.5 PASSING OBJECTS");
	try{
		var original = {howmany: 1};
		var copy = original;
		assertEquals(original.howmany,1);
		copy.howmany = 100;
		assertEquals(copy.howmany,100);
		assertEquals(original.howmany,100);
		success("4.5a Passing object by reference in a call");
		var original = {howmany: 100};
		var nullify = function(o){o.howmany = 0;}
		assertEquals(original.howmany,100);
		nullify(original);
		assertEquals(original.howmany,0);
		success("4.5b Editing a referenced object in a function");
	}catch(e){
		$ERROR("4.5 PASSING OBJECTS : "+e.message);
	}
})();

(function(){
	// 4.6 COMPARING OBJECT
	chapter("4.6 COMPARING OBJECT");
	try{
		var fido = {breed: 'dog'};
		var benji = {breed: 'dog'};
		assertEquals(fido === benji,false);
		assertEquals(fido == benji,false);
		var mydog = benji;
		assertEquals(mydog === benji,true);
		assertEquals(fido === mydog,false);
		success("4.6 Comparing objects is by reference ===");
	}catch(e){
		$ERROR("4.6 COMPARING OBJECT : "+e.message);
	}
})();


(function(){
	// 4.7 BUILTIN OBJECTS
	chapter("4.7 BUILTIN OBJECTS");
	try{
		var o = new Object();
		assertEquals(o.valueOf(),o);
		assertEquals(typeof o.toString,"function");
		success("4.7.1 Object has valueOf, toString");
	}catch(e){
		$ERROR("4.7.1 Object OBJECT : "+e.message);
	}
	try{
		var a = new Array();
		a[0] = 1; a[1] = 2;
		assertEquals(a[0],1);
		assertEquals(a[1],2);
		var a2 = new Array(1,2,3,'four');
		success("4.7.2a construct Array");
		assertEquals(a2[0],1);
		assertEquals(a2[1],2);
		assertEquals(a2[3],'four');
		assertEquals(a2.toString(),'1,2,3,four');
		assertEquals(typeof a2.constructor,"function");
		assertEquals(a2.length,4,"Array.length");
		success("4.7.2b Array.length");
		a2.length=5;
		assertEquals(a2[4],undefined,"Array.length");
		a2.push("six");
		assertEquals(a2[5],"six","Array.push");
		success("4.7.2c Array.push");
		var a3 = a2.slice(1,3);
		assertEquals(a3.length,2);
		assertEquals(a3[1],3);
		success("4.7.2d Array.slice");
	}catch(e){
		$ERROR("4.7.2 ARRAY OBJECT : "+e.message);
	}	
	try{
		assertEquals(Math.PI>3,true,"Math.PI is not set: "+Math.PI);
		assertEquals(Math.round(Math.PI*100)/100,3.14,"Math.PI wrong value: "+Math.PI);
		success("4.7.3a Math.PI, Math.round");
		assertEquals(Math.round(Math.E*100)/100,2.72);
		success("4.7.3b Math.E");
		assertEquals(Math.round(Math.LN10*100)/100,2.30);	
		success("4.7.3c Math.LN10");
		assertEquals(Math.random() > 0,true);
		success("4.7.3d Math.random");
		assertEquals(Math.pow(2,8),256);
		success("4.7.3e Math.pow");
	}catch(e){
		$ERROR("4.7.3 Math obj : "+e.message);
	}
	try{
		var re = new RegExp('j.*t','gmi');
		var re2 = /j.*t/;
		success("4.7.4a Create RegExp");
		assertEquals(re.global,true);
		re.global = false;
		assertEquals(re.global,true);
		success("4.7.4b RegExp.global");
		assertEquals(re.test("Javascript"),true);
		assertEquals(/j.*t/.test("Javascript"),false); // case sensitive
		success("4.7.4c RegExp.test");
		var s = new String('HelloJavaScriptWorld');
		assertEquals(s.match(/a/g).length,2);
		assertEquals(s.match(/j.*a/i)[0],"Java");
		success("4.7.4d String Match with regexp");
		assertEquals(s.search(/j.*a/i),5);
		success("4.7.4e String Search with regexp");
		assertEquals(s.replace(/[A-Z]/g,""),'elloavacriptorld');
		assertEquals(s.replace(/[A-Z]/,""),'elloJavaScriptWorld');
		success("4.7.4e String Replace with regexp");
	}catch(e){
		$ERROR("4.7.4 RegExp : "+e.message);
	}
})();

(function(){
	// 4.8 APPLY / CALL functions
	chapter("4.8 APPLY / CALL functions");
	try{
		var some_obj = {
			name:'Ninja',
			say: function(who){
				return "Hey " + who + ", I am a "+this.name;
			}
		}
		assertEquals(some_obj.say("Dude"),"Hey Dude, I am a Ninja");
		my_obj = {name: 'Guru'};
		assertEquals(some_obj.say.call(my_obj,"Dude"),"Hey Dude, I am a Guru");
		success("4.8.1 some_obj.function.call");
		assertEquals(some_obj.say.apply(my_obj,["Dude"]),"Hey Dude, I am a Guru");
		success("4.8.1 some_obj.function.apply");
	}catch(e){
		$ERROR("4.8 APPLY / CALL : "+e.message);
	}
})();

(function(){
	// 4.9 Try/Catch/Finally
	chapter("4.9 Try/Catch/Finally");
	try{
		success("4.9a try executed");
		throw new Error("Error thrown");
		$ERROR("4.9b no exception was thrown after calling undefined method");
	}catch(e){
		success("4.9b catch executed after error : "+e.message);
	}finally{
		success("4.9c finally executed");
	}
})();





</script><script type="text/javascript">// CHAPTER 5 OF OBJECT ORIENTED JAVASCRIPT
// PROTOTYPE
mainchapter("5 PROTOTYPE");

(function(){
	// 5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE
	chapter("5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE");
	try{
		function Gadget(name, color){
			this.name = name;
			this.color = color;
			this.whatAreYou = function(){
				return this.name+": "+this.color;
			}
		}
		Gadget.prototype.price = 100;
		Gadget.prototype.rating = 3;
		Gadget.prototype.getInfo = function(){
			return this.rating+": "+this.price;
		}
		var newtoy = new Gadget('webcam','black');
		assertEquals(newtoy.name,"webcam");
		assertEquals(newtoy.color,"black");
		assertEquals(newtoy.whatAreYou(),"webcam: black");
		assertEquals(newtoy.price,100);
		assertEquals(newtoy.rating,3);
		success("5.1a Using prototype properties");
		assertEquals(newtoy.getInfo(),"3: 100");
		Gadget.prototype.getInfo = function(){
			return Gadget.prototype.rating+": "+Gadget.prototype.price;
		}
		assertEquals(newtoy.getInfo(),"3: 100");
		success("5.1b Using prototype methods");
		Gadget.prototype.name = 'foo';
		assertEquals(newtoy.name,"webcam");
		delete newtoy.name;
		assertEquals(newtoy.name,"foo");
		newtoy.name="camera";
		assertEquals(newtoy.name,"camera");
		success("5.1c Overwriting prototype's property");
	}catch(e){
		$ERROR("5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE : "+e.message);
	}
})();


(function(){
	// 5.2 HasOwnProperty
	chapter("5.2 Objects and PropertyMethods");
	try{
		function Gadget(name, color){
			this.name = name;
			this.color = color;
			this.whatAreYou = function(){
				return this.name+": "+this.color;
			}
		}
		Gadget.prototype.price = 100;
		Gadget.prototype.rating = 3;
		Gadget.prototype.getInfo = function(){
			return this.rating+": "+this.price;
		}
		var newtoy = new Gadget('webcam','black');
		assertEquals(newtoy.hasOwnProperty('name'),true);
		assertEquals(newtoy.hasOwnProperty('price'),false);
		success("5.2a object.hasOwnProperty( prop )");
		assertEquals(newtoy.propertyIsEnumerable('name'),true);
		assertEquals(newtoy.propertyIsEnumerable('constructor'),false);
		assertEquals(newtoy.propertyIsEnumerable('price'),false);
		assertEquals(newtoy.constructor.prototype.propertyIsEnumerable('price'),true);
		success("5.2b object.propertyIsEnumerable( prop )");
	}catch(e){
		$ERROR("5.2 a/b Objects and PropertyMethods : "+e.message);
	}
	try{
		var monkey = {
			hair: true,
			feeds: 'bananas',
			breathes: 'air'
		};
		function Human(name){
			this.name = name;
		}
		Human.prototype = monkey;
		var george = new Human('George');
		assertEquals(monkey.isPrototypeOf(george),true);
		assertEquals(george.isPrototypeOf(monkey),false);
		success("5.2c object.isPrototypeOf");
	}catch(e){
		$ERROR("5.2 Objects and PropertyMethods : "+e.message);
	}
})();


(function(){
	// 5.3 SOME PROTOTYPE GOTCHAS
	chapter("5.3 SOME PROTOTYPE GOTCHAS");
	try{
		function Dog(){this.tail = true;}
		var benji = new Dog();
		var rusty = new Dog();
		Dog.prototype.say = function(){return 'Woof!';}
		assertEquals(benji.say(),'Woof!');
		assertEquals(rusty.say(),'Woof!');
		assertEquals(typeof benji.say,"function");
		assertEquals(typeof benji.constructor.prototype.say,"function");
		assertEquals(rusty.constructor,benji.constructor.prototype.constructor);
		assertEquals(typeof benji.constructor.prototype.tail, "undefined");
		success("5.3a object.constructor.prototype");
		Dog.prototype = {paws : 4, hair: true};
		assertEquals(typeof benji.paws, "undefined");
		var lucy = new Dog();
		assertEquals(typeof benji.say,"function");
		assertEquals(typeof lucy.say,"undefined");
		assertEquals(lucy.paws,4);
		success("5.3b overwriting prototype");
	}catch(e){
		$ERROR("5.3 SOME PROTOTYPE GOTCHAS : "+e.message);
	}
})();





</script><script type="text/javascript">// CHAPTER 6 OF OBJECT ORIENTED JAVASCRIPT
// INHERITANCE
mainchapter("6 INHERITANCE");

(function(){
	// 6.1 PROTOTYPE CHAINING
	chapter("6.1 PROTOTYPE CHAINING");
	try{
		function Shape(){
			this.name='shape';
			this.toString = function() {return this.name;};
		}
		function TwoDShape(){
			this.name = '2D shape';
		}
		function Triangle(side, height){
			this.name = 'Triangle';
			this.side = side;
			this.height = height;
			this.getArea = function(){return this.side * this.height / 2;};
		}
		TwoDShape.prototype = new Shape();
		Triangle.prototype = new TwoDShape();
		// prevent the negative side effects on the constructor
		TwoDShape.prototype.constructor = TwoDShape;
		Triangle.prototype.constructor = Triangle;
		var my = new Triangle(5,10);
		assertEquals(my.getArea(),25);
		assertEquals(my.toString(),"Triangle");
		success("6.1a Correct inheritance of methods and properties");
		assertEquals(my instanceof Triangle,true);
		assertEquals(my instanceof TwoDShape,true);
		assertEquals(my instanceof Shape,true);
		assertEquals(my instanceof Array,false);
		success("6.1b instanceof superclasses");
		assertEquals(Shape.prototype.isPrototypeOf(my),true);
		assertEquals(TwoDShape.prototype.isPrototypeOf(my),true);
		assertEquals(Triangle.prototype.isPrototypeOf(my),true);
		assertEquals(String.prototype.isPrototypeOf(my),false);
		success("6.1c superclass.isPrototypeOf(subclass) ");
	}catch(e){
		$ERROR("6.1 Prototype fail : "+e.message);
	}
})();

(function(){
	// 6.2 A TEMPORARY CONSTRUCTOR
	chapter("6.2 A TEMPORARY CONSTRUCTOR");
	try{
		function Shape(){}
		Shape.prototype.name='shape';
		Shape.prototype.toString = function(){return this.name;};
		function TwoDShape(){}
		// take care of inheritance
		var F = function(){}
		F.prototype = Shape.prototype;
		TwoDShape.prototype = new F();
		TwoDShape.prototype.constructor = TwoDShape;
		// augment prototype
		TwoDShape.prototype.name = '2D shape';

		function Triangle(side, height){
			this.side = side;
			this.height = height;
		}
		// take care of inheritance
		var F = function(){}
		F.prototype = TwoDShape.prototype;
		Triangle.prototype = new F();
		Triangle.prototype.constructor = Triangle;
		//augment prototype
		Triangle.prototype.getArea = function(){return this.side * this.height / 2;};
		Triangle.prototype.name = 'Triangle';
		
		var my = new Triangle(5,10);
		assertEquals(my.getArea(),25);
		assertEquals(my.toString(),"Triangle");
		success("6.2a Safe inheritance of method");
		var s = new Shape();
		assertEquals(s.name,"shape");
		Triangle.prototype.name = 'Triangle';
		assertEquals(s.name,"shape");
		success("6.2b Safe overwriting prototype property");
	}catch(e){
		$ERROR("6.2 With a temporary constructor: "+e.message);
	}
})();

(function(){
	// 6.3 UBER KEYWORD
	chapter("6.3 UBER KEYWORD");
	try{
		function Shape(){}
		Shape.prototype.name='shape';
		Shape.prototype.toString = function(){
			var result = [];
			if(this.constructor.uber){
				result[result.length] = this.constructor.uber.toString();
			}
			result[result.length] = this.name;
			return result.join(', ');
		};
		function TwoDShape(){}
		// take care of inheritance
		var F = function(){}
		F.prototype = Shape.prototype;
		TwoDShape.prototype = new F();
		TwoDShape.prototype.constructor = TwoDShape;
		TwoDShape.uber = Shape.prototype;
		// augment prototype
		TwoDShape.prototype.name = '2D shape';

		function Triangle(side, height){
			this.side = side;
			this.height = height;
		}
		// take care of inheritance
		var F = function(){}
		F.prototype = TwoDShape.prototype;
		Triangle.prototype = new F();
		Triangle.prototype.constructor = Triangle;
		Triangle.uber = TwoDShape.prototype;
		//augment prototype
		Triangle.prototype.name = 'Triangle';
		Triangle.prototype.getArea = function(){return this.side * this.height / 2;};
		
		var my = new Triangle(5,10);
		assertEquals(my.getArea(),25);
		assertEquals(my.toString(),"shape, 2D shape, Triangle");
		success("6.3 uber performed all super calls");
	}catch(e){
		$ERROR("6.3 uber shoud perform all super calls: "+e.message);
	}
})();

(function(){
	// 6.4 OBJECT CAPABILITY
	chapter("6.4 OBJECT CAPABILITY");
	try{
		// functions should not be in the global scope
		assertEquals(typeof Shape,"undefined");
		assertEquals(typeof TwoDShape,"undefined");
		assertEquals(typeof Triangle,"undefined");
		assertEquals(typeof my,"undefined");
		success("6.4 Previous declared functions are not in the global scope");
	}catch(e){
		$ERROR("6.4 With a temporary constructor: "+e.message);
	}
})();
</script><script type="text/javascript">// CHAPTER 7 OF OBJECT ORIENTED JAVASCRIPT
// THE BROWSER ENVIRONMENT
mainchapter("7 THE BROWSER ENVIRONMENT");

(function(){
	// 7.1 WINDOW OBJECT
	chapter("7.1 WINDOW OBJECT");
	try{
		window.somevar = 1;
		assertEquals(somevar,1);
		success("7.1a window.somevar updates the global somevar");
	}catch(e){
		$ERROR("7.1a window.somevar updates the global somevar : "+e.message);
	}
	try{		
		window.somevar = 5;
		somevar = 3;
		assertEquals(somevar,3);
		assertEquals(window.somevar,3);
	}catch(e){
		$ERROR("7.1b global somevar updates the window.somevar : "+e.message);
	}
	try{
		assertEquals(window.parseInt('123a456'),123);
		success("7.1c window can execute global functions");
	}catch(e){
		$ERROR("7.1c window can execute global functions : "+e.message);
	}
})();

</script>	


</body></html>